﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using RCTools;

namespace exercice5
    {
    public class UseExercice5
        {
        public struct Cellule
            {
            public Int32 valeur;
            public bool isTire;
            public bool isVide;
            }

        public struct Ligne
            {
            public Cellule[] cellule;
            public bool isLigneComplete;
            }

        public struct Carton
            {
            public Ligne[] ligne;
            public bool isLigneComplete;
            public bool isCartonComplet;
            public static Int32 nbLignes = 3;
            public static Int32 nbColonnes = 10;
            }

        enum CartonEnv { RIEN = 0, LIGNE = 1, CARTON = 2 };

        static void Main(string[] args)
            {
            Carton carton = creerCarton();
            afficherCarton(ref carton);
            Int32 min = 1;
            Int32 max = 99;
            Int32 index = 0;
            Int32[] tabN = new Int32[max];
            Int32 res = 0;
            Int32 cpt = 1;
            do
                {
                Thread.Sleep(1000);
                Console.Clear();
                Int32 n = tirageAleatoire(ref tabN, ref index, ref min, ref max);

                System.Console.WriteLine("");
                System.Console.WriteLine("Boule " + cpt + " - Le " + n);
                ++cpt;

                for (int j = 0; j < carton.ligne.Length; ++j)
                    {
                    if (carton.ligne[j].cellule[n / 10].valeur == n)
                        {
                        carton.ligne[j].cellule[n / 10].isTire = true;
                        }
                    }

                afficherCarton(ref carton);
                res = controlerCarton(ref carton);
                }
            while (res != (Int32)CartonEnv.CARTON);
            System.Console.ReadKey();
            }

        static Int32 controlerCarton(ref Carton carton)
            {
            //vérifier si tout le carton est plein
            if (!carton.isLigneComplete)
                {
                int i = 0;
                for (; i < carton.ligne.Length; ++i)
                    {
                    Int32 t = 0;
                    for (int j = 0; j < carton.ligne[i].cellule.Length; ++j)
                        {
                        if (carton.ligne[i].cellule[j].isTire)
                            {
                            ++t;
                            }
                        }

                    if (t == 5)
                        {
                        carton.isLigneComplete = true;
                        carton.ligne[i].isLigneComplete = true;
                        System.Console.WriteLine("BRAVO : Ligne\n\n");
                        System.Console.WriteLine("Pressez une touche pour continuer");
                        System.Console.ReadKey();
                        return (Int32)CartonEnv.LIGNE;
                        }
                    }
                }
            else if (!carton.isCartonComplet)
                {
                Int32 cpt = 1;
                for (int i = 0; i < carton.ligne.Length; ++i)
                    {
                    if (!carton.ligne[i].isLigneComplete)
                        {
                        Int32 t = 0;
                        for (int j = 0; j < carton.ligne[i].cellule.Length; j++)
                            {
                            if (carton.ligne[i].cellule[j].isTire)
                                {
                                ++t;
                                }
                            }
                        if (t == 5)
                            {
                            ++cpt;
                            }
                        }
                    }

                if (cpt == Carton.nbLignes)
                    {
                    carton.isCartonComplet = true;
                    System.Console.WriteLine("BRAVO BRAVO CARTON\n\n");
                    return (Int32)CartonEnv.CARTON;
                    }

                }

            return (Int32)CartonEnv.RIEN;
            }

        private static Carton creerCarton()
            {
            //Création et remplissage de toute la carton
            Carton carton;
            carton.isCartonComplet = false;
            carton.isLigneComplete = false;
            carton.ligne = new Ligne[Carton.nbLignes];
            Int32[] ctr = new Int32[Carton.nbColonnes * Carton.nbLignes];
            Int32 index = 0;
            Int32 min = 0;
            Int32 max = 0;
            Int32 v = 0;

            for (int i = 0; i < carton.ligne.Length; i++)
                {
                carton.ligne[i].cellule = new Cellule[Carton.nbColonnes];
                carton.ligne[i].isLigneComplete = false;

                for (int j = 0; j < carton.ligne[i].cellule.Length; ++j)
                    {
                    if (j == 0) { min = 1; }
                    else { min = j * 10; }
                    if (j == 0) { max = min + RCTools.Numbers.getRandomInteger(1, 9); }
                    else { max = min + RCTools.Numbers.getRandomInteger(1, 9); }

                    do
                        {
                        v = RCTools.Numbers.getRandomInteger(min, max);
                        }
                    while (ctr.Contains(v));

                    ctr[index] = v;
                    ++index;
                    carton.ligne[i].cellule[j].valeur = v;
                    carton.ligne[i].cellule[j].isVide = false;
                    }
                }

            //Triage croissant de chaque colonne
            for (int i = 0; i < carton.ligne[0].cellule.Length; ++i)
                {
                Int32[] tmp = new Int32[Carton.nbLignes];
                for (int j = 0; j < carton.ligne.Length; ++j)
                    {
                    tmp[j] = carton.ligne[j].cellule[i].valeur;
                    }

                tmp = tmp.OrderBy(n => n).ToArray();
                for (int j = 0; j < carton.ligne.Length; ++j)
                    {
                    carton.ligne[j].cellule[i].valeur = tmp[j];
                    }
                }

            //Ajout de 5 cases vide par ligne
            for (int i = 0; i < carton.ligne.Length; ++i)
                {
                Int32[] indexTab = RCTools.Numbers.getRandomTabDifferentIntegers(Carton.nbColonnes / 2, 0, 9);
                for (int j = 0; j < carton.ligne[i].cellule.Length; ++j)
                    {
                    if (indexTab.Contains(j))
                        {
                        carton.ligne[i].cellule[j].valeur = 0;
                        carton.ligne[i].cellule[j].isVide = true;
                        }
                    }
                }
            return carton;
            }

        public static Int32 tirageAleatoire(ref Int32[] tabNumbers, ref Int32 index, ref Int32 min, ref Int32 max)
            {
            if (!tabNumbers.Contains(0))
                {
                return 0;
                }

            Int32 n = 0;
            do
                {
                n = RCTools.Numbers.getRandomInteger(min, max);
                }
            while (tabNumbers.Contains(n));
            if (min == n) { min++; }
            else if (max == n) { max--; }

            tabNumbers[index] = n;
            ++index;

            return n;
            }

        public static void afficherCarton(ref Carton carte)
            {
            foreach (var ligne in carte.ligne)
                {
                foreach (var cellule in ligne.cellule)
                    {
                    if (cellule.valeur != 0)
                        {
                        if (cellule.isTire) { System.Console.Write("(" + cellule.valeur + ")"); }
                        else { System.Console.WriteLine(cellule.valeur); }
                        }
                    else
                        {
                        System.Console.Write("-");
                        }

                    System.Console.Write("\t");
                    }
                System.Console.WriteLine("");
                }
            }
        }
    }
